package cn.xxi.ai.util;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * JSON 工具类，处理 JSON 序列化、反序列化及扁平化操作
 */
@Component
public class JsonUtil {

    /**
     * Spring 容器注入的 ObjectMapper 实例
     */
    private static ObjectMapper objectMapper;

    /**
     * 构造方法注入 ObjectMapper，供静态方法使用
     *
     * @param objectMapper Spring 注入的 ObjectMapper
     */
    @Autowired
    public JsonUtil(ObjectMapper objectMapper) {
        JsonUtil.objectMapper = objectMapper;
    }

    /**
     * 将任意对象序列化为 JSON 字符串
     *
     * @param value 待序列化对象
     * @return JSON 字符串
     */
    public static String toJson(Object value) {
        try {
            return objectMapper.writeValueAsString(value);
        } catch (Exception e) {
            throw new RuntimeException("JSON 序列化失败", e);
        }
    }

    /**
     * 将 JSON 字符串反序列化为指定类型的对象
     *
     * @param json    JSON 字符串
     * @param typeRef 类型引用，用于泛型支持
     * @param <T>     泛型类型
     * @return 反序列化后的对象
     */
    public static <T> T fromJson(String json, TypeReference<T> typeRef) {
        try {
            return objectMapper.readValue(json, typeRef);
        } catch (Exception e) {
            throw new RuntimeException("JSON 反序列化失败", e);
        }
    }

    /**
     * 将 JSON 字符串转换为 Map<String, Object>
     *
     * @param json JSON 字符串
     * @return Map 表示的 JSON 数据
     */
    public static Map<String, Object> toMap(String json) {
        return fromJson(json, new TypeReference<Map<String, Object>>() {});
    }

    /**
     * 将嵌套的 Map 扁平化为单层 Map，key 以点号拼接表示路径
     *
     * 例如：{"a": {"b": 1}} 转换为 {"a.b": 1}
     *
     * @param source 原始嵌套 Map
     * @return 扁平化后的 Map
     */
    public static Map<String, Object> flattenMap(Map<String, Object> source) {
        return flattenMap(source, null);
    }

    /**
     * 递归实现扁平化 Map
     *
     * @param source    当前处理的 Map
     * @param parentKey 上层 key，用于拼接路径
     * @return 扁平化结果 Map
     */
    @SuppressWarnings("unchecked")
    private static Map<String, Object> flattenMap(Map<String, Object> source, String parentKey) {
        Map<String, Object> result = new LinkedHashMap<>();
        for (Map.Entry<String, Object> entry : source.entrySet()) {
            String key = parentKey != null ? parentKey + "." + entry.getKey() : entry.getKey();
            Object value = entry.getValue();
            if (value instanceof Map) {
                // 递归扁平化子 Map
                result.putAll(flattenMap((Map<String, Object>) value, key));
            } else {
                result.put(key, value);
            }
        }
        return result;
    }
}